/**
 * Представления (Views)
 */
$(document).ready(function() {
	VKPlayer = (function($, self, undefined) {

		self.Views = {
            /**
			 *  Представления моделей (Views.models)
			 */
            models: {
                /* Views.models.Track */
                Track: Backbone.View.extend({
                    tagName: "li",
                    className: "audio-list-item",
                    template: _.template($(self.Templates.audioListItem).html()),
                    initialize: function() {
                        this.model.unbind();
                        this.model.view = this;
                        this.model.bind('refresh', this.render, this);
                        this.model.bind('change:attitude', this.updateAttitude, this);
                    },
                    events: {
                        'click .title': "playTrack",
                        'click .control-add': "addTrack",
                        'click .control-remove': "removeTrack",
                        'click .control-restore': "restoreTrack",
                        'click .control-positive': "feedback",
                        'click .control-negative': "feedback",
                        'click .download-btn': "download",
                        'click .video-btn': "video",
                    },
                    download: function (e) {
						e.ignore_show = false;
						e.use_offset = true;
						PLAYER.trigger('downloadQueryUpdate', e);
                    },
					video: function (e) {
						e.ignore_show = false;
						e.use_offset = true;
						PLAYER.trigger('videoQueryUpdate', e);
                    },
					renderDownloadLinks: function() {
						
					},
										
                    render: function() {
                        var $this = $(this.el);
                        if (_.isEqual(this.model, PLAYER.get('track')))
                            PLAYER.trigger('hide');

						var trackData = this.model.toJSON();
						trackData.duration = $.jPlayer.convertTime(trackData.duration);
                        $this.html(this.template(trackData));

                        if (this.model.get('isMyTrack')) {
                            if (this.model.get('removed')) {
                                $this.find('.control-container').addClass('control-restore');
                                $this.addClass('removed');
                            }
                            else {
                                $this.find('.control-container').addClass('control-remove');
                                $this.removeClass('removed');
                            }
                        }
                        else
                            $this.find('.control-container').addClass('control-add');

                        if (_.isEqual(this.model, PLAYER.get('track')))
                            _.delay(this.appendPlayer, 1, this.el);

                        this.updateAttitude();

                        return this;
                    },
                    playTrack: function() {
                        if ($(this.el).is('.removed'))
                            return false;
                        PLAYER.set({track: this.model});
                        PLAYER.trigger('play');
                    },
                    appendPlayer: function(el) {

                        var $this = $(el);

                        $('body').find('.audio-list-item').removeClass('active-track');
                        $this.addClass('active-track');

                        //return;

                        var $content = $this.find('.content');
                        if ($this.is(':visible'))
                            $content.append($(self.Selectors.jPlayerContent));
                        resizeFrame();
                    },
                    addTrack: function() {
                        var $control = $(this.el).find('.control-container');

                        $control
                            .removeClass('control-add')
                            .addClass('control-loading');

                        addAudio(this.model.toJSON())
                            .done(function(data) {
                                if (data.response) {
                                    $control
                                        .removeClass('control-loading')
                                        .addClass('control-sucess');
                                    var tracklistModel = USER.get('tracklist');
                                    var tracks = tracklistModel.get('tracks');
                                    if (!_.isEmpty(tracks)) {
                                        getAudioByIds([USER.get('uid') + '_' + data.response])
                                            .done(function(data) {
                                                if (!_.isEmpty(data)) {
                                                    var track = new self.Models.Track(_.first(data));
                                                    tracks.add(data, {at:0});
                                                }
                                            });
                                    }
                                } else {
                                    $control
                                        .removeClass('control-loading')
                                        .addClass('control-fail');
                                }
                            });
                    },
                    removeTrack: function() {
                        var $this = $(this.el);
                        var $control = $(this.el).find('.control-container');

                        $control
                            .removeClass('control-remove')
                            .addClass('control-loading');

                        var track = this.model;

                        removeAudio(track.toJSON())
                            .done(function(data) {
                                if (data.response) {
                                    track.set({removed:true});
                                    track.trigger('refresh');

                                } else {
                                    $control
                                        .removeClass('control-loading')
                                        .addClass('control-fail');
                                }
                            });
                    },
                    restoreTrack: function() {
                        var $this = $(this.el);
                        var $control = $(this.el).find('.control-container');

                        $control
                            .removeClass('control-restore')
                            .addClass('control-loading');

                        var track = this.model;

                        restoreAudio(track.toJSON())
                            .done(function(data) {
                                if (data.response) {
                                    track.set({removed:false});
                                    track.trigger('refresh');

                                } else {
                                    $control
                                        .removeClass('control-loading')
                                        .addClass('control-fail');
                                }
                            });
                    },
                    updateAttitude: function() {
                        var $this = $(this.el);
                        var $container = $this.find('.feedback-container');
                        var attitude = this.model.get('attitude');
                        $container.removeClass('positive negative').addClass(attitude);
                    },
                    feedback: function(e) {
                        var $control = $(e.target);
                        var attitude = $control.is('.control-positive') ? 'positive' : 'negative';

                        var track = this.model;
                        track.set({attitude: attitude});
                        setFeedbackTrack(track);
                    }
                }),

                /* Views.models.User */
                User: Backbone.View.extend({
                    tagName: "li",
                    templates: {
                        short: _.template($(self.Templates.userShort).html()),
                        full: _.template($(self.Templates.userFull).html())
                    },

                    initialize: function() {
                        this.model.view = this;
                    },

                    events: {
                        'click .folder-control': 'loadAlbums',
                        'click .folder-control.opened': 'render'
                    },

                    render: function() {
                        var $element = $(this.el);
                        $element.html(this.templates.short(this.model.toJSON()));
                        //$element.data('uid', this.model.get('uid'));
                        return this;
                    },

                    renderFull: function(type) {
                        var type = type || 'append';
                        var $element = $(this.el);
                        var $html = this.templates.full(this.model.toJSON());
                        if (type == 'append')
                            $element.append($html);
                        else
                            $element.html($html);
                        //$element.data('uid', this.model.get('uid'));
                        return this;
                    },

                    /**
                     *  Загружает альбомы
                     */
                    loadAlbums: function() {
                        var $this = $(this.el);
                        var $content = $this.find('.content').first();
                        var albums = this.model.get('albums');
                        if (_.isEmpty(albums)) {
                            var model = this.model;
                            getAlbums(this.model.get('uid'))
                                .done(function(result) {
                                    if (result.count) {
                                        var album_list = new self.Collections.Albums(result.list);
                                        var view = new self.Views.collections.Albums({
                                            el: $content,
                                            models: album_list
                                        });
                                        view.render();
                                        resizeFrame();

                                        model.set({albums: album_list});
                                    } else {
                                        $this.removeClass('active');
                                    }
                                }, this)
                        } else {
                            var view = new self.Views.collections.Albums({
                                el: $content,
                                models: albums
                            });
                            view.render();
                            resizeFrame();
                        }
                        ;
                    }
                }),

                /* Views.models.Album */
                Album: Backbone.View.extend({
                    tagName: "li",
                    className: "user-album",
                    template: _.template($(self.Templates.albumShort).html()),
                    render: function() {
                        var $element = $(this.el);
                        $element.html(this.template(this.model.toJSON()));
                        return this;
                    }
                }),

                /* Views.models.Tracklist */
                Tracklist: Backbone.View.extend({
                    tagName: "div",
                    className: "tracklist",
                    initialize: function() {
                        this.model.unbind();
                        this.model.bind('show', this.render, this);
                        this.model.view = this;
                    },
                    render: function() {
                        var tracks = this.model.get('tracks');
                        var owner = this.model.get('owner');

						if (!_.isEmpty(owner)) {
                            var view = new self.Views.models.User({
                                el: $(self.Selectors.content),
                                model: owner
                            });
                            view.renderFull();
                        }

                        if (!_.isEmpty(tracks)) {
                            var view = new self.Views.collections.Tracks({
                                el: $(self.Selectors.content),
                                models: tracks
                            });
                            view.render();
                        }

                        
                        resizeFrame();
						
						if (!_.isEmpty(PLAYER) && _.isEmpty(PLAYER.get('track'))) {
							var $first_track = $('#content .audio-list-item').first();
							$first_track.find('.title').click();
							
							PLAYER.bind('play.first_load',function() {
								$first_track.find('.jp-pause').click();		
								PLAYER.unbind('play.first_load');
							});

						}
                        return this;
                    }

                }),

                /* Views.models.Player */
                Player: Backbone.View.extend({
                    el: $(self.Selectors.mainPlayer),
                    initialize: function() {
                        this.model.unbind();
                        this.model.bind('change:track', this.render, this);
                        this.model.bind('change:muteClass', this.updateVolume, this);
                        this.model.bind('change:loopClass', this.updateLoop, this);
                        this.model.bind('change:shuffleClass', this.updateShuffle, this);
                        this.model.bind('play', this.play, this);
                        this.model.bind('pause', this.pause, this);
                        this.model.bind('resume', this.resume, this);
                        this.model.bind('play_next', this.playNext, this);
                        this.model.bind('timeSync', this.timeSync, this);
                		this.model.bind('volumeChange', this.volumeChange, this);
                		this.model.bind('videoQueryUpdate', this.video, this);
                		this.model.bind('downloadQueryUpdate', this.download, this);

                        /** утаскиваем плеер с поля боя.. */
                        this.model.bind('hide', this.hidePlayer, this);
                        this.model.view = this;

                        this.percent = 0;
                        this.scrobblingAvailable = true;
                        this.MIN_LISTEN_PERCENT = 80;

                        this.render();
                    },
				
                    template: _.template($(self.Templates.largePlayer).html()),
                    events: {
                        'click .player-control .play-button': 'togglePlay',
                        'click .player-control .player-next': 'playNext',
                        'click .player-control .player-prev': 'playPrev',
                        'click .player-volume': 'toggleVolumeMute',
                        'click .player-loop': 'toggleLoop',
                        'click .player-shuffle': 'toggleShuffle',
                        'click .progress .seek-bar': 'seekPosition',
                        'click .volume .jp-volume-bar': 'volumeValue',
                        'click .control-positive': "feedback",
                        'click .control-negative': "feedback",
                        'click .download-btn': "download",
                        'click .video-btn': "video"
                    },

                    render: function() {
                        var $element = $(this.el);
                        var trackModel = this.model.get('track');

                        var dataParams = {
                            artist:'',
                            title: '',
                            attitude: '',
                            hash: '',
                            muteClass: this.model.get('muteClass'),
                            loopClass: this.model.get('loopClass'),
                            shuffleClass: this.model.get('shuffleClass')
                        };

                        if (trackModel) {

                            trackModel
                                .unbind('change:attitude', this.updateAttitude)
                                .bind('change:attitude', this.updateAttitude, this);

                            dataParams = _.extend(dataParams, trackModel.toJSON());

                            $element.removeClass('inactive').addClass('active');
                        } else {
                            $element.addClass('inactive').removeClass('active');
                        }

                        $element.html(this.template(dataParams));
                        return this;
                    },
                    download: function(e) {
						var player = this.model;
                        var popup_id = 'download-popup';
                        var $popup = createPopup(popup_id)

						if (!e.ignore_show) {
							$popup
                            .addClass('popup-layer-center')
				            .html('<div class="loading_progress"><br></div>')
						
							var marginTop = e.use_offset ? e.pageY-200 : e.pageY;
							$popup.data('marginTop', marginTop);
							
							var $anchor = $(e.target);
							$anchor.data('popup_id',popup_id);
							showPopup($anchor, 'click', 'center');
						} else {
							var marginTop = $popup.data('marginTop') || 0;
						}	

                        var track = this.model.get('track');
						var links = track.get('links');
						var query = track.get('download_query');

						if (_.isEmpty(links)) {
							var q = query.replace(/\s/, '+');
							var frame_id = 'download_' + track.get('hash');
							var $iframe = $('<iframe id="' + frame_id + '" style="display:none" src="download/' + q + '"></iframe>');

							$iframe.appendTo('body');
							$iframe.load(function() {
								var $html = $(document.getElementById(frame_id).contentWindow.document);
								var $songs = $html.find('a.song');
								var links = new VKPlayer.Collections.Links;
								$songs.each(function() {
									var $link = $(this);
									var href = $link.attr('href');
									var title = $link.attr('title');
									if (href) {
										links.add({title:title, href:href});
									}
								});
								$iframe.src = '#';
								$iframe.stop().remove();

								if (links.isEmpty()) {
									var tpl = _.template($(self.Templates.downloadSearchErr).html());
									$popup.html(tpl({query: query}));
									$popup.find('.download-query, .read-mode .edit').unbind().bind('click', function(){
										var $container = $(this).closest('.error-info');
										var $textarea = $container.find('textarea');
										$textarea.height($container.find('.download-query').height());
										$container.find('.read-mode').hide();
										$container.find('.edit-mode').show();
										$container.find('.cancel').one('click', function() {
											$container.find('.read-mode').show();
											$container.find('.edit-mode').hide();
										});
										$container.find('.save').one('click', function() {
											track.set({download_query: $textarea.val()});
											player.trigger('downloadQueryUpdate',{ignore_show: true});
											$container.find('.download-query').html($textarea.val());
											$container.find('.read-mode').show();
											$container.find('.edit-mode').hide();
										})
									});
								} else {
									track.set({links: links});
									var view = new self.Views.collections.Links({
										el: $popup,
										models: links
									});
									view.render(query);
								}
								resizeFrame({keepHeights:[marginTop+$popup.height()]});
							});
						} else {
							var view = new self.Views.collections.Links({
								el: $popup,
								models: links
							});
							view.render(query);
							resizeFrame({keepHeights:[marginTop+$popup.height()]});
						}

                    },
                    video: function(e) {
						var player = this.model;
                        var popup_id = 'video-popup';
                        var modelTrack = this.model.get('track');

						var $popup = createPopup(popup_id)

						if (!e.ignore_show) {
							$popup
							.addClass('popup-layer-center')
							.html('<div class="loading_progress"><br></div>');

							var marginTop = e.use_offset ? e.pageY-200 : e.pageY;
							$popup.data('marginTop', marginTop);
							
							var $anchor = $(e.target);
							$anchor.data('popup_id',popup_id);
							showPopup($anchor, 'click', 'center');
						}

						var track = modelTrack.toJSON();
						var query = track.video_query;
						searchVideo({q: query, count: 30})
						.done(function(data) {
							if (!data.count) {
								var tpl = _.template($(self.Templates.videoSearchErr).html());
								$popup.html(tpl({query: query}));
								$popup.find('.video-query, .read-mode .edit').unbind().bind('click', function(){
									var $container = $(this).closest('.error-info');
									var $textarea = $container.find('textarea');
									$textarea.height($container.find('.video-query').height());
									$container.find('.read-mode').hide();
									$container.find('.edit-mode').show();
									$container.find('.cancel').one('click', function() {
										$container.find('.read-mode').show();
										$container.find('.edit-mode').hide();
									});
									$container.find('.save').one('click', function() {
										modelTrack.set({video_query: $textarea.val()});
										player.trigger('videoQueryUpdate',{ignore_show: true});
										$container.find('.video-query').html($textarea.val());
										$container.find('.read-mode').show();
										$container.find('.edit-mode').hide();
									})
								});
							} else {
								player.trigger('pause');
								var video_list = new self.Collections.VideosVk(data.list);
								var playerModel = new self.Models.VideoPlayer({video_list: video_list});
								var playerView = new self.Views.models.VideoPlayer({el:$popup, model:playerModel});
								playerView.render();
								$popup.one('hide.popup', function(){
									player.trigger('resume');
									$popup.find('.video-container').html('');
								});
							}
						});

                    },
                    seekPosition: function(e, d) {
                        var $progress = $(this.el).find('.progress');
                        var $jpProgress = $(self.Selectors.jPlayerContent).find('.jp-progress');
                        var $jpSeekBar = $(self.Selectors.jPlayerContent).find('.jp-seek-bar');
                        var offset = $progress.offset();
                        var percentPos = ( e.pageX - offset.left ) / $progress.width();
                        var positionTo = $jpSeekBar.offset().left + $jpProgress.width() * percentPos;
                        $jpSeekBar.trigger($.Event("click", {pageX: positionTo}));
                    },
                    timeSync: function(data) {
                        if (this.scrobblingAvailable && data.currentTime) {
                            var modelTrack = this.model.get('track');
                            var duration = modelTrack.get('duration');
                            var percent = (data.currentTime / duration).toFixed(2) * 100;
                            var percentDiff = percent - this.percent;

                            if (percentDiff > 2) {
                                /** значит перемотали.. */
                                this.scrobblingAvailable = false;
                            } else {
                                /** копим процент прослушивания.. */
                                this.percent = percent;
                                if (this.percent == this.MIN_LISTEN_PERCENT) {
                                    setScrobbledTrack(modelTrack);
                                    this.scrobblingAvailable = false;
                                }
                            }
                        }
                        /** копипастим таймлайн.. */
                        var time = $(self.Selectors.jPlayerContent).find('.jp-current-time').html();
                        $(this.el).find('.time').html(time);
                        var jpSeekBar = $(self.Selectors.jPlayerContent).find('.jp-seek-bar').attr('style');
                        var jpPlayBar = $(self.Selectors.jPlayerContent).find('.jp-play-bar').attr('style');
                        $(this.el).find('.progress .seek-bar').attr('style', jpSeekBar);
                        $(this.el).find('.progress .play-bar').attr('style', jpPlayBar);
                    },
					volumeValue: function(e, d) {
						var $volume = $(this.el).find('.jp-volume-bar');
						var $jpVolume = $(self.Selectors.jPlayerContent).find('.jp-volume-bar');
						var $jpVBarValue = $(self.Selectors.jPlayerContent).find('.jp-volume-bar-value');
						var offset = $volume.offset();
						var percentPos = ( e.pageX - offset.left ) / $volume.width();
						var positionTo = $jpVBarValue.offset().left + $jpVolume.width() * percentPos;
						$jpVolume.trigger($.Event("click", {pageX: positionTo}));
					},
					volumeChange: function(data) {
						if (data) {
							this.model.set({muted    : data.muted });
							this.model.set({muteClass    : data.muted ? 'muted' : ''});
						}
						/** копипастим таймлайн.. */
						var jpVolumeBar = $(self.Selectors.jPlayerContent).find('.jp-volume-bar-value').attr('style');
						$(this.el).find('.volume .jp-volume-bar-value').attr('style', jpVolumeBar).show();

					},
                    togglePlay: function() {
                        var $control = $(this.el).find('.player-control');
                        var trigger = $control.is('.player-paused') ? 'play' : 'pause';
                        $(self.Selectors.jPlayerContent).find('.jp-' + trigger).click();
                    },

                    toggleVolumeMute: function() {
                        var muted = this.model.isMuted();
                        var trigger = muted ? 'unmute' : 'mute';
                        $(self.Selectors.jPlayerContent).find('.jp-' + trigger).click();
                    },

                    toggleLoop: function() {
                        var loop = this.model.isLoop();
                        var trigger = loop ? 'repeat-off' : 'repeat';
                        $(self.Selectors.jPlayerContent).find('.jp-' + trigger).click();
                    },

                    toggleShuffle: function() {
                        var shuffle = this.model.isShuffle();
                        var shuffle = ! shuffle;
                        this.model.trigger('shuffleChange', {shuffle: shuffle})
                    },

                    pause: function() {
                        var $control = $(this.el).find('.player-control');
						$(self.Selectors.jPlayerContent).find('.jp-pause').click();
                        $control.removeClass('player-plays').addClass('player-paused');
                    },

                    resume: function() {
                        var $control = $(this.el).find('.player-control');
						$(self.Selectors.jPlayerContent).find('.jp-play').click();
                        $control.removeClass('player-paused').addClass('player-plays');
                    },
					
                    play: function(data) {
                        downloadingOn();

                        if (data) {
                            var scrobblingDisabled = data.scrobblingDisabled;
                        }

                        var $control = $(this.el).find('.player-control');

                        $control.removeClass('player-paused').addClass('player-plays');

                        var modelTrack = this.model.get('track');

                        if (!modelTrack)
                            return;

                        if (_.isEmpty(modelTrack.get('link_audio_id')))
                            setTrackLink(modelTrack);

                        $(self.Selectors.jPlayerId).jPlayer("setMedia", {
                            mp3: modelTrack.get('url')
                        });
                        $(self.Selectors.jPlayerId).jPlayer("play");
                        /** начинаем скробблить */
                        if (!scrobblingDisabled) {
                            this.percent = 0;
                            this.scrobblingAvailable = true;
                        }

                        this.model.set({tracklist: modelTrack.get('tracklist')});
                        modelTrack.trigger('refresh');
                    },
                    playNext: function () {
                        var modelTrack = this.model.get('track');
                        var tracklist = this.model.get('tracklist');
                        var tracks = tracklist.get('tracks');

						if (this.model.isShuffle()) {
                        	modelTrack = tracks.random(modelTrack, tracks.length);
						} else {
                        	modelTrack = tracks.next(modelTrack);
						}

                        PLAYER.set({track: modelTrack});
                        PLAYER.trigger('play');
                    },
                    playPrev: function () {
                        var modelTrack = this.model.get('track');
                        var tracklist = this.model.get('tracklist');
                        var tracks = tracklist.get('tracks');

                        modelTrack = tracks.prev(modelTrack);

                        PLAYER.set({track: modelTrack});
                        PLAYER.trigger('play');
                    },

                    hidePlayer: function () {
                        $('#player-hider').append($(self.Selectors.jPlayerContent));
                    },
                    updateVolume: function() {
                        var $this = $(this.el);
                        var muteClass = this.model.get('muteClass')
                        $this.find('.player-volume').removeClass('muted').addClass(muteClass);
                    },
                    updateLoop: function() {
                        var $this = $(this.el);
                        var loopClass = this.model.get('loopClass')
                        $this.find('.player-loop').removeClass('repeat').addClass(loopClass);
                    },
                    updateShuffle: function() {
                        var $this = $(this.el);
                        var shuffleClass = this.model.get('shuffleClass')
                        $this.find('.player-shuffle').removeClass('shuffle').addClass(shuffleClass);
                    },
                    updateAttitude: function() {
                        var $this = $(this.el);
                        var $container = $this.find('.feedback-container');
                        var track = this.model.get('track');
                        var attitude = track.get('attitude');
                        $container.removeClass('positive negative').addClass(attitude);
                    },
                    feedback: function(e) {
                        var $control = $(e.target);
                        var attitude = $control.is('.control-positive') ? 'positive' : 'negative';

                        var track = this.model.get('track');
                        track.set({attitude: attitude});
                        setFeedbackTrack(track);
                    }

                }),

				/* Views.models.VideoPlayer */
                VideoPlayer: Backbone.View.extend({
                    initialize: function() {
						this.type = this.model.get('type');
						this.model.unbind();
						this.model.bind('show', this.render, this);
						this.model.bind('change:current_video', this.renderCurrentVideo, this);
                        this.model.view = this;
                    },
                    template: _.template($(self.Templates.videoPlayerWrap).html()),
					events: {
                        'show': 'render'
					},
					selectVideo: function() {
					},
					renderCurrentVideo: function() {
						var $content = $(this.el);
						var currentVideo = this.model.get('current_video');
						var view = new self.Views.models.VideoVk({model: currentVideo});
						this.bindClickThumb({
							video: currentVideo,
							model: this.model
						});
						var $video = $(view.renderFull().el);
						$content.find('.video-container').html('').append($video);
						$content.find('.video-title').html(currentVideo.get('title'));
					},
					bindClickThumb: function(data) {
						data.video.bind('clickThumb',function(){
							data.model.set({current_video:this});
						}, data.video);
					},
					render: function() {
						var $content = $(this.el);
						var videoPlayerView = this;
						var videoPlayerModel = this.model;
						var video_list = videoPlayerModel.get('video_list');
						
						if (!_.isEmpty(video_list) && !video_list.isEmpty()) {
							var view = new self.Views.collections.VideosVk({models:video_list});
							view.render();
							view.options.models.each(function(video) {
								videoPlayerView.bindClickThumb({
									video: video,
									model: videoPlayerModel
								});
							});
							var $thumbs = $(view.el);
						}

						$content.html(this.template());
						$content.find('.thumbs').append($thumbs);
						
						
						var $slider = $content.find('.video-controls');
						$slider.find('.thumbs-prev').addClass('inactive');
						var lastOffset = $slider.find('.video-item').last().position().left;
						var containerOffset = $slider.find('.thumbs').margin().left;
						var wrapOffset = $slider.find('.thumbs-wrap').width();
						if ( (lastOffset + containerOffset) < wrapOffset )
							$slider.find('.thumbs-next').addClass('inactive');
						else
							$slider.find('.thumbs-next').addClass('active');


						$slider.find('.thumbs-prev, .thumbs-next').on('click', function() {
							var $this = $(this);
							$prevBtn = $this.parent().find('.thumbs-prev');
							$nextBtn = $this.parent().find('.thumbs-next');

							var direction = $this.is('.thumbs-next') ? '-' : '+';
							var $wrap = $this.parent().find('.thumbs-wrap');
							var $container = $this.parent().find('.thumbs');

							if ( $this.is('.inactive') || $container.is(':animated') )
								return false;

							var wrapOffset = $wrap.width();
							$container.animate({'marginLeft': direction +'=' + wrapOffset + 'px'}, 500, function() {
								var lastOffset = $container.find('.video-item').last().position().left;
								var containerOffset = $container.margin().left;

								if ( (lastOffset + containerOffset) < wrapOffset )
									$nextBtn.removeClass('active').addClass('inactive');
								else
									$nextBtn.removeClass('inactive').addClass('active');

								if (containerOffset == 0)
									$prevBtn.removeClass('active').addClass('inactive');
								else
									$prevBtn.removeClass('inactive').addClass('active');
							});
						});



						if (_.isEmpty(videoPlayerModel.get('current_video'))) {
							//video_list.first().trigger('clickThumb');
							if (!_.isEmpty(video_list) && !video_list.isEmpty()) {
								$(video_list.first().view.el).find('.clickThumb-trigger').click();
							}
						}
					}

                }),

				/* Views.models.Link */
                Link: Backbone.View.extend({
                    tagName: "li",
                    className: "donload-link",
                    template: _.template($(self.Templates.downloadLink).html()),
					initialize: function() {
                        this.model.unbind();
                        this.model.view = this;
                        this.model.bind('refresh', this.render, this);
                    },
                    render: function() {
                        var $element = $(this.el);
                        $element.html(this.template(this.model.toJSON()));
                        return this;
                    }
                }),

				/* Views.models.VideoVk */
                VideoVk: Backbone.View.extend({
					tagName: "span",
                    className: "video-item",
                    template: {
						thumb: _.template($(self.Templates.videoThumbVk).html()),
						full: _.template($(self.Templates.videoFullVk).html())
					},
					events: {
						'click .clickThumb-trigger' : "onClick"
					},

					onClick: function() {
						this.model.trigger('clickThumb');
                        var $element = $(this.el);
						$element.siblings('.video-item').removeClass('active');
						$element.addClass('active');
					},

					initialize: function() {
                        this.model.unbind();
                        this.model.view = this;
                    },
                    renderThumb: function() {
                        var $element = $(this.el);
                        $element.html(this.template.thumb(this.model.toJSON()));
                        return this;
                    },
                    renderFull: function() {
                        var $element = $(this.el);
                        $element.html(this.template.full(this.model.toJSON()));
                        return this;
                    }
                })

            }, //* end Views.models */

            /**
             * Представления коллекций (Views.collections)
             */
            collections: {

				/* Views.collections.Tracks */
                Tracks: Backbone.View.extend({
                    initialize: function() {
						$(this.el).unbind();
                        this.page = 1;
                        this.limit = 10;
                    },
                    templates:{
                        pager: _.template($(self.Templates.moreTracks).html()),
                        list: _.template($(self.Templates.audioTracks).html())
                    },
                    events: {
                        //'click .more-tracks': 'more'
                    },
                    more: function() {
                        this.render(this.page + 1);
                    },
                    render: function(page) {
                        var $element = $(this.el);
                        $element.find('.more-tracks').remove();

                        //if (!page)
                            //$element.html('');

                        var size = this.options.models.size();
                        var page = page || 1;
                        var limit = this.limit;

                        var offset = (page - 1) * limit;
                        var pages_amount = Math.ceil(size / limit);

                        var $list = $(this.templates.list());
                        for (var i = offset; i < offset + limit; i++) {
                            var track = this.options.models.at(i);

                            if (_.isEmpty(track)) break;

                            track.set({num: i+1});

                            var view = new self.Views.models.Track({model: track});
                            $list.append(view.render().el);
                        }

                        var $pager = $(this.templates.pager());

                        $list.hide();
                        $element.append($list);
                        $list.fadeIn();

                        if (page < pages_amount)
						{	
							$element
                            .append($pager);
							this.delegateEvents({'click .more-tracks': 'more'})
						}

                        //$list.animate({opacity: 1}, 777);
                        this.page = page;

                        resizeFrame();

                        return this;
                    },

                    /**@deprecated*/
                    _render: function() {
                        var $element = $(this.el);
                        $element.html('');
                        var t1 = new Date;
                        var $df = $('<div></div>');

//						for (var i = 0; i < 20; i++) {
//							var track = this.options.models.at(i);
//
//							if ( _.isEmpty(track) ) break;
//							var view = new Views.models.Track({model: track});
//							$df.append(view.render().el);
//
//						}


                        this.options.models.each(function(track) {
                            var view = new self.Views.models.Track({model: track});
                            $df.append(view.render().el);
                        });

                        $element.append($df);
//						var $lastTrack = $element.find('.audio-list-item').last();
//						$lastTrack.click(function() {
//						});

                        var t2 = new Date;

                        return this;
                    }
                }),

                Users: Backbone.View.extend({
                    initialize: function() {
                        this.page = 1;
                        this.limit = 10;
                    },
                    templates:{
                        pager: _.template($(self.Templates.slidePager).html()),
                        list: _.template($(self.Templates.friends).html())
                    },
                    events: {
                        'click .page-prev.active': 'prevPage',
                        'click .page-next.active': 'nextPage'
                    },
                    prevPage: function() {
                        this.render(this.page - 1);
                    },
                    nextPage: function() {
                        this.render(this.page + 1);
                    },

                    render: function(page) {
                        var $element = $(this.el);
                        $element.html('');

                        var size = this.options.models.size();
                        var page = page || 1;
                        var limit = this.limit;

                        var offset = (page - 1) * limit;
                        var pages_amount = Math.ceil(size / limit);

                        var $list = $(this.templates.list());
                        for (var i = offset; i < offset + limit; i++) {
                            var user = this.options.models.at(i);

                            if (_.isEmpty(user)) break;

                            var view = new self.Views.models.User({model: user});
                            $list.append(view.render().el);
                        }

                        var $pager = this.templates.pager({
                            prev: page > 1 ? 'active' : 'inactive',
                            next: page < pages_amount ? 'active' : 'inactive'
                        });

                        $element.append($list);
                        $element.append($pager);
                        $list.animate({opacity: 1}, 777);
                        this.page = page;

                        resizeFrame();

                        return this;
                    }
                }),

                Albums: Backbone.View.extend({
                    render: function() {
                        var $element = $(this.el);
                        $element.html('');
                        this.options.models.each(function(album) {
                            var view = new self.Views.models.Album({model: album});
                            $element.append(view.render().el);
                        });
                        return this;
                    }
                }),

				Links: Backbone.View.extend({
                    render: function(title) {
                        var $element = $(this.el);
						var tpl = _.template($(self.Templates.downloadLinks).html());
						$element.html(tpl({title: title||''}));
						var $container = $element.find('.container');	
                        this.options.models.each(function(link) {
                            var view = new self.Views.models.Link({model: link});
                            $container.append(view.render().el);
                        })
                        return this;
                    }
                }),

				VideosVk: Backbone.View.extend({
					tagName: "div",
                    className: "video-list",
                    render: function() {
                        var $element = $(this.el);
                        $element.html('');
                        this.options.models.each(function(video) {
                            var view = new self.Views.models.VideoVk({model: video});
                            $element.append($(view.renderThumb().el));
                        });
                        return this;
                    },
					getHtml: function() {
						var $element = $(this.render().el);
						return $element.html();
					}
                })
				
            },  //* end Views.collections */

            /**
             * Представление приложения (Views.App)
             */
            App: Backbone.View.extend({
                el: $("#page"),
                initialize: function() {
                    this._chunksRequired = ['player', 'user'];
                    this._chunksInited = [];
                },
                events: {
                    "click #menu-albums-trigger": "loadMyAlbums",
                    "click #menu-friends-trigger": "showMyFriends"
                },
                isInited: function() {
                    return _.isEmpty(_.difference(this._chunksRequired, this._chunksInited));
                },
                setInit: function(chunk) {
                    this._chunksInited.push(chunk);
                    if (this.isInited())
                        this.trigger('inited');
                },

                loadMyAlbums: function() {

                    var $folder = $('#menu-albums-trigger').closest('.folder');
                    var $content = $folder.find('.content').first();
                    /*
                     * @TODO Надо както переделать... вызывать метод
                     * модели..
                     */
                    if (_.isEmpty(USER.get('albums'))) {
                        $content.html(_.template($(self.Templates.loaderSmall).html()))
                        getAlbums(USER.get('uid'))
						.done(function(result) {
							if (result) {
								var album_list = new self.Collections.Albums(result.list);
								album_list.add({
									title:'Все композиции',
									album_id:0,
									owner_id: USER.get('uid')
								}, {at:0});
								var view = new self.Views.collections.Albums({
									el: $content,
									models: album_list
								});
								view.render();
								resizeFrame();

								USER.set({albums: album_list});
							}
						});
                    }
                },

                showMyFriends: function() {

                    ROUTER.flashAnchor('friendlist')

                    var $folder = $('#menu-friends-trigger').closest('.folder');
                    var $content = $folder.find('.content').first();

                    var showFriends = _.after(1, function() {
                        var friend_list = USER.get('friends');
                        friend_list.comparator = function(user) {
                            return user.get('first_name');
                        };
                        friend_list.sort();

                        var view = new self.Views.collections.Users({
                            el: $content,
                            models: friend_list
                        });
                        view.render();
                        resizeFrame();
                    });

                    if (_.isEmpty(USER.get('friends'))) {
                        USER.loadFriends();
                        USER.bind('friends_loaded', function() {
                            showFriends();
                        }, this);
                    } else {
                        showFriends();
                    }
                }

            })    //* end Views.App */
        };

	return self;

	})(jQuery, VKPlayer || {});
});
